﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bittorrent.Bencode.Collections;
using System.Net;
using Bittorrent.Client.Tracker.Exceptions;
using Bittorrent.Bencode;
using Bittorrent.Extentions;

namespace Bittorrent.Client.Tracker {
    internal class DictionaryPeer : IPeer {
        public DictionaryPeer(Dictionary dictonary) {
            PeerId = dictonary.GetOptionalString("peer id");
            PeerEndPoint = GetPeerEndPoint(dictonary);
        }

        #region IPeer Members

        /// <summary>
        /// Gets peer's self-selected ID (in compact mode this string is empty).
        /// </summary>
        public string PeerId { get; private set; }

        /// <summary>
        /// Gets connection EndPoint (IPAddress and port) for the peer.
        /// </summary>
        public IPEndPoint PeerEndPoint { get; private set; }

        #endregion

        #region private members

        private static IPEndPoint GetPeerEndPoint(Dictionary dictonary) {
            // TODO: Rewrite this crap. Why the f does it look like this.
            if (!dictonary.ContainsKey("ip")) {
                throw new HttpTrackerException(ErrorResource.MissingIPDictionaryPeerMessage);
            }

            if (!dictonary.ContainsKey("port")) {
                throw new HttpTrackerException(ErrorResource.MissingPortDictionaryPeerMessage);
            }

            var ip = dictonary["ip"] as ByteString;
            if (ip == null) {
                throw new HttpTrackerException(ErrorResource.UnkownIPTypeDictionaryPeerMessage);
            }

            var port = dictonary["port"] as Integer;
            if (port == null) {
                throw new HttpTrackerException(ErrorResource.UnkownPortTypeDictionaryPeerMessage);
            }

            IPAddress ipAddress;
            if (!IPAddress.TryParse(ip.String, out ipAddress)) {
                throw new HttpTrackerException(ErrorResource.MallformedIPDictionaryPeerMessage);
            }

            return new IPEndPoint(ipAddress, (int)port.Value);
        }

        #endregion
    }
}
